package com.nationart.backend.shiro.filter;

import java.io.IOException;

import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.subject.Subject;
import org.apache.shiro.web.filter.authc.AuthenticatingFilter;
import org.apache.shiro.web.filter.authc.FormAuthenticationFilter;
import org.apache.shiro.web.util.WebUtils;

import com.alibaba.druid.util.StringUtils;
import com.alibaba.fastjson.JSONObject;
import com.nationart.backend.entity.SysUser;
import com.nationart.backend.shiro.OAuthToken;
import com.nationart.backend.util.HttpUtils;
import com.nationart.backend.util.Response;

public class LoginFilter extends FormAuthenticationFilter {

	@Override
	protected boolean onAccessDenied(ServletRequest request, ServletResponse response) throws Exception {
		// TODO Auto-generated method stub
		// 获取请求token，如果token不存在，直接返回401
		HttpServletRequest req = (HttpServletRequest) request;
		String token = getRequestToken(req);
		Subject subject = getSubject(request, response);
		if (subject != null && subject.isAuthenticated()) {
			return true;
		}
		HttpServletResponse httpResponse = (HttpServletResponse) response;
		if (StringUtils.isEmpty(token)) {
			if (HttpUtils.isAjaxRequest((HttpServletRequest) request)) {

				String json = JSONObject.toJSONString(Response.error(500, "invalid token"));
				httpResponse.getWriter().print(json);
			} else {
				httpResponse.sendRedirect(request.getServletContext().getContextPath() + "/signin");
			}
			return false;
		}

		return executeLogin(request, response);
	}

	@Override
	protected boolean onLoginFailure(AuthenticationToken token, AuthenticationException e, ServletRequest request,
			ServletResponse response) {
		// TODO Auto-generated method stub
		HttpServletResponse httpResponse = (HttpServletResponse) response;
		httpResponse.setContentType("application/json;charset=utf-8");
		try {
			// 处理登录失败的异常
			Throwable throwable = e.getCause() == null ? e : e.getCause();
			Response r = Response.error(500, throwable.getMessage());

			String json = JSONObject.toJSONString(r);
			httpResponse.getWriter().print(json);
		} catch (IOException e1) {

		}

		return false;
	}

	@Override
	protected boolean isAccessAllowed(ServletRequest request, ServletResponse response, Object mappedValue) {
		// TODO Auto-generated method stub
		return false;
	}

	/**
	 * 获取请求的token
	 */
	private String getRequestToken(HttpServletRequest httpRequest) {
		// 从header中获取token
		String token = httpRequest.getHeader("token");

		// 如果header中不存在token，则从参数中获取token
		if (StringUtils.isEmpty(token)) {
			token = httpRequest.getParameter("token");
		}

		return token;
	}

	@Override
	protected AuthenticationToken createToken(ServletRequest request, ServletResponse response) {
		// TODO Auto-generated method stub
		// 获取请求token
		String token = getRequestToken((HttpServletRequest) request);

		if (StringUtils.isEmpty(token)) {
			return null;
		}

		return new OAuthToken(token);
	}

	@Override
	protected boolean onLoginSuccess(AuthenticationToken token, Subject subject, ServletRequest request,
			ServletResponse response) throws Exception {
		// TODO Auto-generated method stub
		// 获取已登录的用户信息
		SysUser activeUser = (SysUser) subject.getPrincipal();
		// 获取session
		HttpServletRequest httpServletRequest = WebUtils.toHttp(request);
		HttpSession session = httpServletRequest.getSession();
		// 把用户信息保存到session
		session.setAttribute("activeUser", activeUser);
		return super.onLoginSuccess(token, subject, request, response);
	}

}
